package com.ccut.xunfeiSpringboot.service.impl;

import cn.xfyun.api.IseClient;
import cn.xfyun.model.response.ise.IseResponseData;
import cn.xfyun.service.ise.AbstractIseWebSocketListener;
import com.ccut.xunfeiSpringboot.service.IseClientService;
import okhttp3.Response;
import okhttp3.WebSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Base64;
import java.util.concurrent.CompletableFuture;

@Service
public class IseClientServiceImpl implements IseClientService {

    private static final Logger logger = LoggerFactory.getLogger(IseClientServiceImpl.class);
    private static final Base64.Decoder BASE64_DECODER = Base64.getDecoder();

    @Value("${xfyun.appid}")
    private String appId;

    @Value("${xfyun.apikey}")
    private String apiKey;

    @Value("${xfyun.apiSecret}")
    private String apiSecret;

    @Async
    @Override
    public CompletableFuture<String> evaluateAudioFile(MultipartFile audioFile, String text) throws IOException {
        CompletableFuture<String> future = new CompletableFuture<>();

        if (audioFile.isEmpty()) {
            future.completeExceptionally(new IllegalArgumentException("音频文件不能为空"));
            return future;
        }

        Path tempFile = null;
        try {
            tempFile = Files.createTempFile("ise_", ".pcm");
            Files.copy(audioFile.getInputStream(), tempFile, StandardCopyOption.REPLACE_EXISTING);

            IseClient iseClient = createIseClient(text);

            Path finalTempFile = tempFile;
            AbstractIseWebSocketListener listener = new AbstractIseWebSocketListener() {
                @Override
                public void onSuccess(WebSocket webSocket, IseResponseData response) {
                    try {
                        if (response.getData() == null || response.getData().getData() == null) {
                            throw new IllegalStateException("服务返回数据为空");
                        }
                        String decodedResult = new String(
                                BASE64_DECODER.decode(response.getData().getData()),
                                "UTF-8"
                        );
                        future.complete(decodedResult);
                    } catch (Exception e) {
                        future.completeExceptionally(new IOException("Base64解码失败", e));
                    } finally {
                        deleteTempFile(finalTempFile);
                    }
                }

                @Override
                public void onFail(WebSocket webSocket, Throwable throwable, Response response) {
                    String errorMsg = "评测失败: " + (response != null ? response.message() : throwable.getMessage());
                    logger.error(errorMsg, throwable);
                    future.completeExceptionally(new IOException(errorMsg, throwable));
                    deleteTempFile(finalTempFile);
                }
            };

            iseClient.send(tempFile.toFile(), listener);
        } catch (Exception e) {
            logger.error("评测请求初始化失败", e);
            future.completeExceptionally(new IOException("评测系统初始化失败", e));
            if (tempFile != null) {
                deleteTempFile(tempFile);
            }
        }

        return future;
    }

    private IseClient createIseClient(String text) throws IOException {
        try {
            return new IseClient.Builder()
                    .signature(appId, apiKey, apiSecret)
                    .addSub("ise")
                    .addEnt("cn_vip")
                    .addCategory("read_sentence")
                    .addTte("utf-8")
                    .addText('\uFEFF' + text)
                    .addRstcd("utf8")
                    .build();
        } catch (Exception e) {
            throw new IOException("创建评测客户端失败", e);
        }
    }

    private void deleteTempFile(Path tempFile) {
        try {
            if (tempFile != null) {
                Files.deleteIfExists(tempFile);
            }
        } catch (IOException e) {
            logger.warn("临时文件删除失败: {}", tempFile, e);
        }
    }
}